home *** CD-ROM | disk | FTP | other *** search
/ PC-X 1997 October / pcx14_9710.iso / swag / files.swg / 0102_Very Nice File Handling For BP.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1997-03-04  |  36.6 KB  |  1,519 lines

  1. {$A+,B-,D-,E-,F-,G+,I-,L-,N+,O-,P-,Q-,R-,S-,T-,V+,X+,Y-}
  2.  
  3. Unit UFile95;
  4.  
  5. {A lot of declarations in this unit belong in other units, such as
  6.  Move32 (UMemory); TBoolean/TByte/TChar - UGlobal. Unit was modified to
  7.  be standalone.}
  8.  
  9.  
  10. (* **************************************************************
  11.      TO COMPILE  UFILE95  YOU NEED TO COMPILE THE  UMULTI  UNIT
  12.          WHOSE SOURCE CAN BE FOUND AT THE END OF THIS FILE
  13.    **************************************************************
  14.                   PLEASE PUBLISH THIS IN THE SWAG
  15.    ************************************************************** *)
  16.  
  17.  
  18. Interface {Nothing!}
  19.  
  20. Const Author = 'UFile95 v6.2, 05-Feb-97, 1995-1997.'+
  21.                'Written by Gil Shapira.'+
  22.                'Bug or other reports to:  gilsh@ibm.net';
  23.  
  24. {Nicer looks ;-) }
  25. Type TBoolean = Boolean;
  26.      TPointer = Pointer;
  27.      TChar = Char;
  28.      TByte = Byte;
  29.      TWord = Word;
  30.      THalf = ShortInt;
  31.      TInt = Integer;
  32.      TDouble = LongInt;
  33.  
  34. Type THandle = TWord;
  35.      TError = TWord;
  36.  
  37. {File modes}
  38. Const fmRead = 0;
  39.       fmWrite = 1;
  40.       fmReadWrite = 2;
  41.       fmDenyAll = 16;
  42.       fmDenyWrite = 32;
  43.       fmDenyRead = 48;
  44.       fmDenyNone = 64;
  45.  
  46. {File seek origins}
  47. Const foStart = 0;
  48.       foCurrent = 1;
  49.       foEnd = 2;
  50.  
  51. {File attributes}
  52. Const faReadOnly = 1;
  53.       faHidden = 2;
  54.       faSystem = 4;
  55.       faVolume = 8;
  56.       faDirectory = 16;
  57.       faArchive = 32;
  58.       faAnyFile = 63;
  59.  
  60. {File parts}
  61. Const fcExtension = 1;
  62.       fcFileName = 2;
  63.       fcDirectory = 4;
  64.       fcWildcards = 8;
  65.  
  66. {Search record for DOS interrupt 21h}
  67. Type PSearch = ^TSearch;
  68.      TSearch = Record
  69.                 SearchDrive: TChar;
  70.                 SearchTemplate: Array [1..11] Of TByte;
  71.                 SearchAttr: TByte;
  72.                 DirEntry: TWord;
  73.                 StartCluster: TWord;
  74.                 Reserved: Array [1..4] Of TByte;
  75.                 Attr: TByte;
  76.                 Time: TWord;
  77.                 Date: TWord;
  78.                 Size: TDouble;
  79.                 Name: Array [1..13] Of TChar;
  80.                End;
  81.  
  82. {Search record for Windows '95 interrupt 21h}
  83. Type PSearch95 = ^TSearch95;
  84.      TSearch95 = Record
  85.                   Handle: TWord;
  86.                   Attr: TDouble;
  87.                   Creation: Comp;
  88.                   LastAccess: Comp;
  89.                   LastModify: Comp;
  90.                   SizeHi: TDouble;
  91.                   SizeLo: TDouble;
  92.                   Reserved: Array [1..8] Of TByte;
  93.                   Name: Array [0..259] Of TChar;
  94.                   ShortName: Array [0..13] Of TChar;
  95.                  End;
  96.  
  97. Var LockLevel,
  98.     FileMode,
  99.     FindAttr,
  100.     CopyAttr,
  101.     DeleteAttr,
  102.     CreateAttr: TWord;
  103.     flError: TError;
  104.     isError,
  105.     Using95: TBoolean;
  106.  
  107.  {Creates a new directory; only ONE directory at a time.}
  108. Procedure CreateDir(PathName: PChar);
  109.  {Removes an existing directory; should not be current directory}
  110. Procedure RemoveDir(PathName: PChar);
  111.  {Makes the specified directory the current directory,
  112.   without changing the current drive}
  113. Procedure ChangeDir(PathName: PChar);
  114.  {Returns the current directory path}
  115. Procedure CurrentDir(CurDir: PChar);
  116.  {Makes the specified directory the current directory,
  117.   and changes the current drive if needed}
  118. Procedure ChangePath(PathName: PChar);
  119.  {Creates a virtual drive for the path specified; should be
  120.   used ONLY under Windows '95}
  121. Procedure Subst(Drive: TChar; PathName: PChar);
  122.  {Returns the path for the virtual drive specified; should be
  123.   used ONLY under Windows '95}
  124. Procedure QuerySubst(Drive: TChar; Var PathName: PChar);
  125.  {Terminates the virtual drive association; should be
  126.   used ONLY under Windows '95}
  127. Procedure DeleteSubst(Drive: TChar);
  128.  {Creates a new file}
  129. Function Create(FileName: PChar): THandle;
  130.  {Replaces an existing file, erasing its content}
  131. Function Replace(FileName: PChar): THandle;
  132.  {Opens an existing file}
  133. Function Open(FileName: PChar): THandle;
  134.  {Duplicated a file handle}
  135. Function Duplicate(Handle: THandle): THandle;
  136.  {Changes the position in the file; use the file origin
  137.   constants for Origin}
  138. Function Seek(Handle: THandle; Position: TDouble; Origin: TByte): TDouble;
  139.  {Returns the current position in the file}
  140. Function FilePos(Handle: THandle): TDouble;
  141.  {Returns the size of the file}
  142. Function FileSize(Handle: THandle): TDouble;
  143.  {Splits the path to directory, filename (8), and extension (4)}
  144. Function FSplit(Path,Dir,Name,Ext: PChar): TByte;
  145.  {Expands a short/long filename}
  146. Procedure FExpand(Path,Result: PChar);
  147.  {Return the file attributes}
  148. Function GetFileAttr(FileName: PChar): TByte;
  149.  {Changes the file attributes}
  150. Procedure SetFileAttr(FileName: PChar; Attr: TByte);
  151.  {Returns a file's true name}
  152. Procedure TrueName(FileName,TrueFileName: PChar);
  153.  {Returns a file's short name (8.3); should be used only
  154.   under Windows '95}
  155. Procedure ShortName(FileName,ShortFileName: PChar);
  156.  {Generates a short name (8.3) for a long file name; should
  157.   be used only under Windows '95}
  158. Procedure LongToShort(FileName,ShortFileName: PChar);
  159.  {Deletes a file}
  160. Procedure Delete(FileName: PChar);
  161.  {Renames a file; can move a file between directories on the same drive}
  162. Procedure Rename(FileName,NewName: PChar);
  163.  {Deletes any bytes from the position in the file to its end}
  164. Procedure Truncate(Handle: THandle);
  165.  {Flushes any file buffers}
  166. Procedure Commit(Handle: THandle);
  167.  {Closes a file, writing any changes}
  168. Procedure Close(Handle: THandle);
  169.  {Reads a block of bytes to a buffer}
  170. Function BlockRead(Handle: THandle; Var Buff; Count: TWord): TWord;
  171.  {Writes a block of bytes to a file}
  172. Function BlockWrite(Handle: THandle; Var Buff; Count: TWord): TWord;
  173.  {Locks a drive to allow direct drive accesses}
  174. Procedure LockDrive(Drive: TChar);
  175.  {Unlocks a drive to disallow direct drive accesses}
  176. Procedure UnlockDrive(Drive: TChar);
  177.  {Changes the current drive}
  178. Procedure ChangeDrive(Drive: TChar);
  179.  {Returns the current drive}
  180. Function CurrentDrive: TChar;
  181.  {Disables a drive, rendering it completely inaccessible until reenabled}
  182. Procedure DisableDrive(Drive: TChar);
  183.  {Enables a previously disabled drive}
  184. Procedure EnableDrive(Drive: TChar);
  185.  {Turns a FLOPPY drive's led on}
  186. Procedure TurnLedOn(Drive: TChar);
  187.  {Turns a FLOPPY drive's led off}
  188. Procedure TurnLedOff(Drive: TChar);
  189.  {Returns a drive's information}
  190. Function DriveInformation(Drive: TChar; Var DriveType: TByte; Volume: TPointer; Var Serial,TotalSpace,FreeSpace,
  191.                            ClusterSize: TDouble): TBoolean;
  192.  {Returns the amount of bytes free on a drive}
  193. Function DiskFree(Drive: TChar): TDouble;
  194.  {Returns the total amount of bytes used on a drive}
  195. Function DiskSize(Drive: TChar): TDouble;
  196.  {Resets a drive, flushing its buffers}
  197. Procedure ResetDrive(Drive: TChar);
  198.  {Quits from the calling program}
  199. Procedure Halt(ErrorLevel: TByte);
  200.  {Runs another program; READ NOTE IN THE CODE ITSELF!}
  201. Procedure Exec(Prog,Params: PChar);
  202.  {Sets the data transfer area; not to be changed normally}
  203. Procedure SetDTA(Address: TPointer);
  204.  {Returns the data transfer area's address}
  205. Function GetDTA: TPointer;
  206.  {Finds the first file; able to process long filenames; should be
  207.   used ONLY under Windows '95}
  208. Procedure FindFirst95(FileSpec: PChar; Attr: TByte; Var Search: TSearch95);
  209.  {Returns the next file; should be
  210.   used ONLY under Windows '95}
  211. Procedure FindNext95(Var Search: TSearch95);
  212.  {Closes a file search; MUST be done at the end of a search; should be
  213.   used ONLY under Windows '95}
  214. Procedure FindClose95(Var Search: TSearch95);
  215.  {Finds the first file}
  216. Procedure FindFirst(FileSpec: PChar; Attr: TWord; Var Search: TSearch);
  217.  {Finds the next file}
  218. Procedure FindNext(Var Search: TSearch);
  219.  {Moves 4 bytes in each move; much faster; (80386 processors
  220.   and faster ONLY)}
  221. Procedure Move32(Var Source,Target; Len: TWord);
  222.  
  223.  
  224. Implementation uses UMulti,Strings; {This is of course the Strings unit
  225.                                      you got with your Borland/Turbo Pascal.
  226.                                      The UMulti unit is at the end of this
  227.                                      file. Compile if first.}
  228.  
  229. Var DTA: TPointer;
  230.     ParameterBlock: TPointer;
  231.     Block: Array [1..40] Of TByte;
  232.  
  233. Procedure Move32(Var Source,Target; Len: TWord); Assembler;
  234. Asm
  235.   Push          Ds
  236.   Mov           Cx,Len
  237.   Jcxz         @End
  238.   Lds           Si,Source
  239.   Les           Di,Target
  240.   Cld
  241.   ShR           Cx,1
  242.   Jnc          @Sw
  243.   MovSb
  244.  @Sw:
  245.   Shr           Cx,1
  246.   Jnc          @Sd
  247.   MovSw
  248.  @Sd:
  249.   Db            66h,0F3h,0A5h {Rep MovSd}
  250.  @End:
  251.   Pop           Ds
  252. End;
  253.  
  254. Procedure CreateDir(PathName: PChar); Assembler;
  255. Asm
  256.   Push          Ds
  257.   Mov           Ax,7139h
  258.   Cmp           Using95,True
  259.   Je           @Use95
  260.   Mov           Ax,3900h
  261.  @Use95:
  262.   Lds           Dx,PathName
  263.   Int           21h
  264.   Pop           Ds
  265.   Jnc          @End
  266.   Mov           flError,Ax
  267.   Mov           isError,True
  268.  @End:
  269. End;
  270.  
  271. Procedure RemoveDir(PathName: PChar); Assembler;
  272. Asm
  273.   Push          Ds
  274.   Mov           Ax,713Ah
  275.   Cmp           Using95,True
  276.   Je           @Use95
  277.   Mov           Ax,3A00h
  278.  @Use95:
  279.   Lds           Dx,PathName
  280.   Int           21h
  281.   Pop           Ds
  282.   Jnc          @End
  283.   Mov           flError,Ax
  284.   Mov           isError,True
  285.  @End:
  286. End;
  287.  
  288. Procedure ChangeDir(PathName: PChar); Assembler;
  289. Asm
  290.   Push          Ds
  291.   Mov           Ax,713Bh
  292.   Cmp           Using95,True
  293.   Je           @Use95
  294.   Mov           Ax,3B00h
  295.  @Use95:
  296.   Lds           Dx,PathName
  297.   Int           21h
  298.   Pop           Ds
  299.   Jnc          @End
  300.   Mov           flError,Ax
  301.   Mov           isError,True
  302.  @End:
  303. End;
  304.  
  305. Procedure CurrentDir(CurDir: PChar); Assembler;
  306. Asm
  307.   Push          Ds
  308.   Mov           Ax,7147h
  309.   Cmp           Using95,True
  310.   Je           @Use95
  311.   Mov           Ax,4700h
  312.  @Use95:
  313.   Xor           Dl,Dl
  314.   Lds           Si,CurDir
  315.   Int           21h
  316.   Pop           Ds
  317.   Jnc          @End
  318.   Mov           flError,Ax
  319.   Mov           isError,True
  320.  @End:
  321. End;
  322.  
  323. Procedure ChangePath(PathName: PChar); Assembler;
  324. Asm
  325.   Push          Ds
  326.   Lds           Si,PathName
  327.   LodSw
  328.   Cmp           Ah,':'
  329.   Jne          @NoDrive
  330.   Cmp           Al,'A'
  331.   Jb           @NoUpper
  332.   Cmp           Al,'Z'
  333.   Ja           @NoUpper
  334.   Sub           Al,20h
  335.  @NoUpper:
  336.   Xor           Ah,Ah
  337.   Push          Ax
  338.   Call          ChangeDrive
  339.  @NoDrive:
  340.   Lds           Si,PathName
  341.   LodSw
  342.   Cmp           Ah,':'
  343.   Jne          @Added
  344.   Dec           Si
  345.   Dec           Si
  346.  @Added:
  347.   Mov           Ax,Ds
  348.   Mov           Es,Ax
  349.   Pop           Ds
  350.   Push          Es
  351.   Push          Si
  352.   Call          ChangeDir
  353.  @End:
  354. End;
  355.  
  356. Procedure Subst(Drive: TChar; PathName: PChar); Assembler;
  357. Asm
  358.   Push          Ds
  359.   Cmp           Using95,True
  360.   Jne           @End
  361.   Mov           Ax,71AAh
  362.   Xor           Bh,Bh
  363.   Mov           Bl,Drive
  364.   Sub           Bl,64
  365.   Lds           Dx,PathName
  366.   Int           21h
  367.   Pop           Ds
  368.   Jnc          @End
  369.   Mov           flError,Ax
  370.   Mov           isError,True
  371.  @End:
  372. End;
  373.  
  374. Procedure QuerySubst(Drive: TChar; Var PathName: PChar); Assembler;
  375. Asm
  376.   Push          Ds
  377.   Cmp           Using95,True
  378.   Jne           @End
  379.   Mov           Ax,71AAh
  380.   Mov           Bh,02h
  381.   Mov           Bl,Drive
  382.   Sub           Bl,64
  383.   Lds           Dx,PathName
  384.   Int           21h
  385.   Pop           Ds
  386.   Jnc          @End
  387.   Mov           flError,Ax
  388.   Mov           isError,True
  389.  @End:
  390. End;
  391.  
  392. Procedure DeleteSubst(Drive: TChar); Assembler;
  393. Asm
  394.   Cmp           Using95,True
  395.   Jne           @End
  396.   Mov           Ax,71AAh
  397.   Mov           Bh,01h
  398.   Mov           Bl,Drive
  399.   Sub           Bl,64
  400.   Int           21h
  401.   Jnc          @End
  402.   Mov           flError,Ax
  403.   Mov           isError,True
  404.  @End:
  405. End;
  406.  
  407. Function Create(FileName: PChar): THandle; Assembler;
  408. Asm
  409.   Push          Ds
  410.   Mov           Ax,716Ch
  411.   Cmp           Using95,True
  412.   Je           @Use95
  413.   Mov           Ax,6C00h
  414.  @Use95:
  415.   Mov           Bl,Byte Ptr FileMode
  416.   Mov           Bh,32
  417.   Mov           Cx,Word Ptr CreateAttr
  418.   Mov           Dx,0000000000010000b
  419.   Lds           Si,FileName
  420.   Int           21h
  421.   Pop           Ds
  422.   Jnc          @End
  423.   Mov           flError,Ax
  424.   Mov           isError,True
  425.   Xor           Ax,Ax
  426.  @End:
  427. End;
  428.  
  429. Function Replace(FileName: PChar): THandle; Assembler;
  430. Asm
  431.   Push          Ds
  432.   Mov           Ax,716Ch
  433.   Cmp           Using95,True
  434.   Je           @Use95
  435.   Mov           Ax,6C00h
  436.  @Use95:
  437.   Mov           Bl,Byte Ptr FileMode
  438.   Mov           Bh,32
  439.   Mov           Cx,32
  440.   Mov           Dx,0000000000010010b
  441.   Lds           Si,FileName
  442.   Int           21h
  443.   Pop           Ds
  444.   Jnc          @End
  445.   Mov           flError,Ax
  446.   Mov           isError,True
  447.   Xor           Ax,Ax
  448.  @End:
  449. End;
  450.  
  451. Function Open(FileName: PChar): THandle; Assembler;
  452. Asm
  453.   Push          Ds
  454.   Mov           Ax,716Ch
  455.   Cmp           Using95,True
  456.   Je           @Use95
  457.   Mov           Ax,6C00h
  458.  @Use95:
  459.   Mov           Bl,Byte Ptr FileMode
  460.   Mov           Bh,32
  461.   Mov           Cx,32
  462.   Mov           Dx,0000000000000001b
  463.   Lds           Si,FileName
  464.   Int           21h
  465.   Pop           Ds
  466.   Jnc          @End
  467.   Mov           flError,Ax
  468.   Mov           isError,True
  469.   Xor           Ax,Ax
  470.  @End:
  471. End;
  472.  
  473. Function Duplicate(Handle: THandle): THandle; Assembler;
  474. Asm
  475.   Mov           Ah,45h
  476.   Mov           Bx,Word Ptr Handle
  477.   Int           21h
  478.   Jnc          @End
  479.   Mov           flError,Ax
  480.   Mov           isError,True
  481.   Xor           Ax,Ax
  482.  @End:
  483. End;
  484.  
  485. Function Seek(Handle: THandle; Position: TDouble; Origin: TByte): TDouble; Assembler;
  486. Asm
  487.   Mov           Ah,42h
  488.   Mov           Al,Byte Ptr Origin
  489.   Mov           Bx,Word Ptr Handle
  490.   Mov           Cx,Word Ptr Position
  491.   Mov           Dx,Word Ptr Position+2
  492.   Int           21h
  493.   Jnc          @End
  494.   Mov           flError,Ax
  495.   Mov           isError,True
  496.   Xor           Ax,Ax
  497.  @End:
  498. End;
  499.  
  500. Function FilePos(Handle: THandle): TDouble; Assembler;
  501. Asm
  502.   Mov           Ah,42h
  503.   Mov           Al,foCurrent
  504.   Mov           Bx,Word Ptr Handle
  505.   Xor           Cx,Cx
  506.   Xor           Dx,Dx
  507.   Int           21h
  508.   Jnc          @End
  509.   Mov           flError,Ax
  510.   Mov           isError,True
  511.   Xor           Ax,Ax
  512.   Xor           Dx,Dx
  513.  @End:
  514. End;
  515.  
  516. Function FileSize(Handle: THandle): TDouble; Assembler;
  517. Var FPos: TDouble;
  518. Asm
  519.   Push          Word Ptr Handle
  520.   Call          FilePos
  521.   Cmp           Word Ptr flError,0
  522.   Jne          @Error
  523.   Mov           Word Ptr FPos,Dx
  524.   Mov           Word Ptr FPos+2,Ax
  525.   Mov           Ah,42h
  526.   Mov           Al,foEnd
  527.   Mov           Bx,Word Ptr Handle
  528.   Xor           Cx,Cx
  529.   Xor           Dx,Dx
  530.   Int           21h
  531.   Jc           @Error
  532.   Pusha
  533.   Mov           Ah,42h
  534.   Mov           Al,foStart
  535.   Mov           Bx,Word Ptr Handle
  536.   Mov           Cx,Word Ptr FPos
  537.   Mov           Dx,Word Ptr FPos+2
  538.   Int           21h
  539.   Jnc          @End
  540.  @Error:
  541.   Mov           flError,Ax
  542.   Mov           isError,True
  543.   Xor           Ax,Ax
  544.   Xor           Dx,Dx
  545.  @End:
  546.   Popa
  547. End;
  548.  
  549. Function FSplit(Path,Dir,Name,Ext: PChar): TByte;
  550. {Based on the Borland Pascal run-time library and EnhancedDos (Andrew Eigus);
  551.  Modified for long filename support by Gil Shapira}
  552. Var DirLen,NameLen,Flags: TWord;
  553.     NamePtr,ExtPtr: PChar;
  554. Begin
  555.  NamePtr:=StrRScan(Path,'\');
  556.  If (NamePtr=Nil) Then NamePtr:=StrRScan(Path,':');
  557.  If (NamePtr=Nil) Then NamePtr:=Path Else Inc(NamePtr);
  558.  ExtPtr:=StrScan(NamePtr,'.');
  559.  If (ExtPtr=Nil) Then ExtPtr:=StrEnd(NamePtr);
  560.  DirLen:=NamePtr-Path;
  561.  NameLen:=ExtPtr-NamePtr;
  562.  Flags:=0;
  563.  If (StrScan(NamePtr,'?')<>Nil) Or (StrScan(NamePtr,'*')<>Nil) Then Flags:=fcWildcards;
  564.  If (DirLen<>0) Then Flags:=Flags Or fcDirectory;
  565.  If (NameLen<>0) Then Flags:=Flags Or fcFilename;
  566.  If (ExtPtr[0]<>#0) Then Flags:=Flags Or fcExtension;
  567.  If (Dir<>Nil) Then StrLCopy(Dir,Path,DirLen);
  568.  If (Name<>Nil) Then StrLCopy(Name,NamePtr,NameLen);
  569.  If (Ext<>Nil) Then StrLCopy(Ext,ExtPtr,4);
  570.  FSplit:=Flags;
  571. End;
  572.  
  573. Procedure FExpand(Path,Result: PChar); Assembler;
  574. Asm
  575.   Push            Ds
  576.   Cld
  577.   Lds            Si,Path
  578.   Push          Ds
  579.   Push          Si
  580.   Call          StrLen
  581.   Mov           Cx,Ax
  582.   Add            Cx,Si
  583.   Les            Di,Result
  584.   LodSw
  585.   Cmp            Si,Cx
  586.   Ja           @1
  587.   Cmp            Ah,':'                  {If DriveLetter not present...}
  588.   Jne          @1                       {use default drive}
  589.   Cmp           Al,'a'                  {If DriveLetter below 'a'...}
  590.   Jb           @2
  591.   Cmp            Al,'z'                  {or above 'z'...}
  592.   Ja           @2                       {jump...}
  593.   Sub            Al,20h                  {or else make it uppercase...}
  594.   Jmp           @2                       {and jump}
  595.  @1:                                    {Get current drive}
  596.   Dec            Si
  597.   Dec            Si
  598.   Mov            Ah,19h
  599.   Int            21h
  600.   Add            Al,'A'
  601.   Mov            Ah,':'
  602.  @2:
  603.   StoSw                                 {Write drive letter}
  604.   Cmp            Si,Cx                   {If source is only drive letter...}
  605.   Je           @21                      {jump...}
  606.   Cmp            Byte Ptr [Si],'\'       {if it includes path...}
  607.   Je           @3                       {jump}
  608.  @21:                                   {Get current directory}
  609.   Sub            Al,'A'-1
  610.   Mov            Dl,Al
  611.   Mov            Al,'\'
  612.   StoSb
  613.   Push            Si
  614.   Push            Ds
  615.   Mov            Ax,7147h
  616.   Mov            Si,Di
  617.   Push            Es
  618.   Pop            Ds
  619.   Int            21h
  620.   Pop            Ds
  621.   Pop            Si
  622.   Jc           @3
  623.   Cmp            Byte Ptr Es:[Di],0
  624.   Je           @3
  625.   Push            Cx
  626.   Mov            Cx,-1
  627.   Xor            Al,Al
  628.   RepNe            ScaSb
  629.   Dec            Di
  630.   Mov            Al,'\'
  631.   StoSb
  632.   Pop            Cx
  633.  @3:
  634.   Sub       Cx,Si
  635.   Rep            MovSb
  636.   Xor            Al,Al
  637.   StoSb
  638.   Lds            Si,Result
  639.   Mov            Di,Si
  640.   Push            Di
  641.  @4:
  642.   LodSb
  643.   Or            Al,Al
  644.   Je           @6
  645.   Cmp            Al,'\'
  646.   Je           @6
  647.   Cmp            Al,'a'
  648.   Jb           @5
  649.   Cmp            Al,'z'
  650.   Ja           @5
  651.  @5:
  652.   StoSb
  653.   Jmp           @4
  654.  @6:
  655.   Cmp            Word Ptr [Di-2],'.\'
  656.   Jne           @7
  657.   Dec            Di
  658.   Dec            Di
  659.   Jmp           @9
  660.  @7:
  661.   Cmp            Word Ptr [Di-2],'..'
  662.   Jne           @9
  663.   Cmp            Byte Ptr [Di-3],'\'
  664.   Jne           @9
  665.   Sub            Di,3
  666.   Cmp            Byte Ptr [Di-1],':'
  667.   Je           @9
  668.  @8:
  669.   Dec            Di
  670.   Cmp            Byte Ptr [Di],'\'
  671.   Jne           @8
  672.  @9:
  673.   Or            Al,Al
  674.   Jne           @5
  675.   Cmp            Byte Ptr [Di-1],':'
  676.   Jne           @10
  677.   Mov            Al,'\'
  678.   StoSb
  679.  @10:
  680.   Xor           Al,Al
  681.   StoSb
  682.   Pop           Di
  683.   Pop            Ds
  684. End;
  685.  
  686. Function GetFileAttr(FileName: PChar): TByte; Assembler;
  687. Asm
  688.   Push          Ds
  689.   Mov           Ax,7143h
  690.   Cmp           Using95,True
  691.   Je           @Use95
  692.   Mov           Ax,4300h
  693.  @Use95:
  694.   Xor           Bl,Bl
  695.   Lds           Dx,FileName
  696.   Int           21h
  697.   Pop           Ds
  698.   Jnc          @OK
  699.   Mov           flError,Ax
  700.   Mov           isError,True
  701.   Xor           Ax,Ax
  702.   Jmp          @End
  703.  @OK:
  704.   Mov           Ax,Cx
  705.  @End:
  706. End;
  707.  
  708. Procedure SetFileAttr(FileName: PChar; Attr: TByte); Assembler;
  709. Asm
  710.   Push          Ds
  711.   Mov           Ax,7143h
  712.   Cmp           Using95,True
  713.   Je           @Use95
  714.   Mov           Ax,4301h
  715.  @Use95:
  716.   Mov           Bl,01h
  717.   Mov           Cl,Byte Ptr Attr
  718.   Xor           Ch,Ch
  719.   Lds           Dx,FileName
  720.   Int           21h
  721.   Pop           Ds
  722.   Jnc          @End
  723.   Mov           flError,Ax
  724.   Mov           isError,True
  725.  @End:
  726. End;
  727.  
  728. Procedure TrueName(FileName,TrueFileName: PChar); Assembler;
  729. Asm
  730.   Push          Ds
  731.   Mov           Ax,7160h
  732.   Cmp           Using95,True
  733.   Je           @Use95
  734.   Mov           Ax,6000h
  735.  @Use95:
  736.   Mov           Cx,0002h
  737.   Lds           Si,FileName
  738.   Les           Di,TrueFileName
  739.   Int           21h
  740.   Pop           Ds
  741.   Jnc          @End
  742.   Mov           flError,Ax
  743.   Mov           isError,True
  744.  @End:
  745. End;
  746.  
  747. Procedure ShortName(FileName,ShortFileName: PChar); Assembler;
  748. Asm
  749.   Push          Ds
  750.   Cmp           Using95,True
  751.   Jne          @End
  752.   Mov           Ax,7160h
  753.   Mov           Cx,0001h
  754.   Lds           Si,FileName
  755.   Les           Di,ShortFileName
  756.   Int           21h
  757.   Pop           Ds
  758.   Jnc          @End
  759.   Mov           flError,Ax
  760.   Mov           isError,True
  761.  @End:
  762. End;
  763.  
  764. Procedure LongToShort(FileName,ShortFileName: PChar); Assembler;
  765. Asm
  766.   Cld
  767.   Push          Ds
  768.   Mov           Ax,71A8h
  769.   Cmp           Using95,True
  770.   Jne          @End
  771.   Lds           Si,FileName
  772.   Les           Di,ShortFileName
  773.   Xor           Dx,Dx
  774.   Int           21h
  775.   Pop           Ds
  776.   Jnc          @End
  777.   Mov           flError,Ax
  778.   Mov           isError,True
  779.  @End:
  780. End;
  781.  
  782. Procedure Delete(FileName: PChar); Assembler;
  783. Asm
  784.   Push          Ds
  785.   Mov           Ax,7141h
  786.   Cmp           Using95,True
  787.   Je           @Use95
  788.   Mov           Ax,4100h
  789.  @Use95:
  790.   Lds           Dx,FileName
  791.   Mov           Si,0001h
  792.   Mov           Cl,Byte Ptr DeleteAttr
  793.   Xor           Ch,Ch
  794.   Int           21h
  795.   Pop           Ds
  796.   Jnc          @End
  797.   Mov           flError,Ax
  798.   Mov           isError,True
  799.  @End:
  800. End;
  801.  
  802. Procedure Rename(FileName,NewName: PChar); Assembler;
  803. Asm
  804.   Push          Ds
  805.   Mov           Ax,7156h
  806.   Cmp           Using95,True
  807.   Je           @Use95
  808.   Mov           Ax,5600h
  809.  @Use95:
  810.   Lds           Dx,FileName
  811.   Les           Di,NewName
  812.   Int           21h
  813.   Pop           Ds
  814.   Jnc          @End
  815.   Mov           flError,Ax
  816.   Mov           isError,True
  817.  @End:
  818. End;
  819.  
  820. Procedure Close(Handle: THandle); Assembler;
  821. Asm
  822.   Mov           Ah,3Eh
  823.   Mov           Bx,Word Ptr Handle
  824.   Int           21h
  825.   Jnc          @End
  826.   Mov           flError,Ax
  827.   Mov           isError,True
  828.  @End:
  829. End;
  830.  
  831. Procedure Truncate(Handle: THandle); Assembler;
  832. Asm
  833.   Push          Ds
  834.   Mov           Ah,40h
  835.   Mov           Bx,Word Ptr Handle
  836.   Xor           Cx,Cx
  837.   Int           21h
  838.   Pop           Ds
  839.   Jnc          @End
  840.   Mov           flError,Ax
  841.   Mov           isError,True
  842.  @End:
  843. End;
  844.  
  845. Procedure Commit(Handle: THandle); Assembler;
  846. Asm
  847.   Mov           Ah,68h
  848.   Mov           Bx,Word Ptr Handle
  849.   Int           21h
  850.   Jnc          @End
  851.   Mov           flError,Ax
  852.   Mov           isError,True
  853.  @End:
  854. End;
  855.  
  856. Function BlockRead(Handle: THandle; Var Buff; Count: TWord): TWord; Assembler;
  857. Asm
  858.   Push          Ds
  859.   Mov           Ah,3Fh
  860.   Mov           Bx,Word Ptr Handle
  861.   Mov           Cx,Count
  862.   Jcxz         @End
  863.   Lds           Dx,Buff
  864.   Int           21h
  865.   Pop           Ds
  866.   Jnc          @End
  867.   Mov           flError,Ax
  868.   Mov           isError,True
  869.   Xor           Ax,Ax
  870.  @End:
  871. End;
  872.  
  873. Function BlockWrite(Handle: THandle; Var Buff; Count: TWord): TWord; Assembler;
  874. Asm
  875.   Push          Ds
  876.   Mov           Ah,40h
  877.   Mov           Bx,Word Ptr Handle
  878.   Mov           Cx,Count
  879.   Jcxz         @End
  880.   Lds           Dx,Buff
  881.   Int           21h
  882.   Pop           Ds
  883.   Jnc          @End
  884.   Mov           flError,Ax
  885.   Mov           isError,True
  886.   Xor           Ax,Ax
  887.  @End:
  888. End;
  889.  
  890. Procedure LockDrive(Drive: TChar); Assembler;
  891. Asm
  892.   Mov           Ax,440Dh
  893.   Mov           Cx,084Ah
  894.   Mov           Bl,Drive
  895.   Sub           Bl,'@'
  896.   Mov           Bh,Byte Ptr LockLevel
  897.   Mov           Dx,0000000000000001b
  898.   Int           21h
  899.   Jnc          @End
  900.   Mov           flError,Ax
  901.   Mov           isError,True
  902.  @End:
  903. End;
  904.  
  905. Procedure UnlockDrive(Drive: TChar); Assembler;
  906. Asm
  907.   Mov           Ax,440Dh
  908.   Mov           Cx,086Ah
  909.   Mov           Bl,Drive
  910.   Sub           Bl,'@'
  911.   Int           21h
  912.   Jnc          @End
  913.   Mov           flError,Ax
  914.   Mov           isError,True
  915.  @End:
  916. End;
  917.  
  918. Procedure ChangeDrive(Drive: TChar); Assembler;
  919. Asm
  920.   Mov           Ah,0Eh
  921.   Mov           Dl,Byte Ptr Drive
  922.   Sub           Dl,'A'
  923.   Int           21h
  924. End;
  925.  
  926. Function CurrentDrive: TChar; Assembler;
  927. Asm
  928.   Mov           Ah,19h
  929.   Int           21h
  930.   Add           Al,'A'
  931. End;
  932.  
  933. Procedure EnableDrive(Drive: TChar); Assembler;
  934. Asm
  935.   Mov           Ax,5F07h
  936.   Mov           Dl,Byte Ptr Drive
  937.   Sub           Dl,'A'
  938.   Int           21h
  939.   Jnc          @End
  940.   Mov           flError,Ax
  941.   Mov           isError,True
  942.   Xor           Ax,Ax
  943.  @End:
  944. End;
  945.  
  946. Procedure DisableDrive(Drive: TChar); Assembler;
  947. Asm
  948.   Mov           Ax,5F08h
  949.   Mov           Dl,Byte Ptr Drive
  950.   Sub           Dl,'A'
  951.   Int           21h
  952.   Jnc          @End
  953.   Mov           flError,Ax
  954.   Mov           isError,True
  955.   Xor           Ax,Ax
  956.  @End:
  957. End;
  958.  
  959. Procedure FindFirst95(FileSpec: PChar; Attr: TByte; Var Search: TSearch95); Assembler;
  960. Asm
  961.   Push          Ds
  962.   Mov           Ax,714Eh
  963.   Xor           Si,Si
  964.   Xor           Ch,Ch
  965.   Mov           Cl,Attr
  966.   Lds           Dx,FileSpec
  967.   Les           Di,Search
  968.   Inc           Di
  969.   Inc           Di
  970.   Int           21h
  971.   Dec           Di
  972.   Dec           Di
  973.   StoSw
  974.   Pop           Ds
  975.   Jnc          @End
  976.   Mov           flError,Ax
  977.   Mov           isError,True
  978.  @End:
  979. End;
  980.  
  981. Procedure FindNext95(Var Search: TSearch95); Assembler;
  982. Asm
  983.   Push          Ds
  984.   Lds           Si,Search
  985.   LodSw
  986.   Mov           Bx,Ax
  987.   Mov           Ax,714Fh
  988.   Xor           Si,Si
  989.   Les           Di,Search
  990.   Inc           Di
  991.   Inc           Di
  992.   Int           21h
  993.   Pop           Ds
  994.   Jnc          @End
  995.   Mov           flError,Ax
  996.   Mov           isError,True
  997.  @End:
  998. End;
  999.  
  1000. Procedure FindClose95(Var Search: TSearch95); Assembler;
  1001. Asm
  1002.   Push          Ds
  1003.   Lds           Si,Search
  1004.   LodSw
  1005.   Mov           Bx,Ax
  1006.   Mov           Ax,71A1h
  1007.   Int           21h
  1008.   Pop           Ds
  1009.   Jnc          @End
  1010.   Mov           flError,Ax
  1011.   Mov           isError,True
  1012.  @End:
  1013. End;
  1014.  
  1015. Procedure FindFirst(FileSpec: PChar; Attr: TWord; Var Search: TSearch); Assembler;
  1016. Asm
  1017.   Push          Ds
  1018.   Mov           Ah,4Eh
  1019.   Mov           Cx,Attr
  1020.   Lds           Dx,FileSpec
  1021.   Int           21h
  1022.   Jnc          @Transfer
  1023.   Mov           flError,Ax
  1024.   Mov           isError,True
  1025.   Jmp          @End
  1026.  @Transfer:
  1027.   Les           Si,DTA
  1028.   Push          Es
  1029.   Push          Si
  1030.   Les           Si,Search
  1031.   Push          Es
  1032.   Push          Si
  1033.   Push          43
  1034.   Call          Move32
  1035.  @End:
  1036.   Pop           Ds
  1037. End;
  1038.  
  1039. Procedure FindNext(Var Search: TSearch); Assembler;
  1040. Asm
  1041.   Push          Ds
  1042.   Les           Si,Search
  1043.   Push          Es
  1044.   Push          Si
  1045.   Les           Si,DTA
  1046.   Push          Es
  1047.   Push          Si
  1048.   Push          43
  1049.   Call          Move32
  1050.   Mov           Ah,4Fh
  1051.   Int           21h
  1052.   Jnc          @Transfer
  1053.   Mov           flError,Ax
  1054.   Mov           isError,True
  1055.   Jmp          @End
  1056.  @Transfer:
  1057.   Les           Si,DTA
  1058.   Push          Es
  1059.   Push          Si
  1060.   Les           Si,Search
  1061.   Push          Es
  1062.   Push          Si
  1063.   Push          43
  1064.   Call          Move32
  1065.  @End:
  1066.   Pop           Ds
  1067. End;
  1068.  
  1069. Procedure Halt(ErrorLevel: TByte); Assembler;
  1070. Asm
  1071.   Mov           Ah,4Ch
  1072.   Mov           Al,Byte Ptr ErrorLevel
  1073.   Int           21h
  1074. End;
  1075.  
  1076. Procedure Exec(Prog,Params: PChar); Assembler;
  1077. {For some reason, you need to add a space before the Params
  1078.  string. For example:
  1079.  
  1080.  To run:
  1081.    C:\COMMAND.COM /C DIR C:\
  1082.  The variables need to be like this:
  1083.    Prog:='C:\COMMAND.COM';
  1084.    Params:=' /C DIR C:\';   {Notice the space before the /C}
  1085.  
  1086. Var ShortFileName: PChar;
  1087. Asm
  1088.   Push          Ds
  1089. {Building ParameterBlock}
  1090.   Cld
  1091.   Les           Di,ParameterBlock
  1092.   Lds           Si,Params
  1093.   Inc           Di
  1094.   Inc           Di
  1095.   Mov           Ax,Si
  1096.   StoSw
  1097.   Mov           Ax,Ds
  1098.   StoSw
  1099.   Db            86h,0D0h,90h,86h,0C2h,86h,0C9h
  1100.   Pop           Ds
  1101.   Push          Ds
  1102.   Cmp           Using95,True
  1103.   Je           @Use95
  1104.   Lds           Dx,Prog
  1105.   Jmp          @OK
  1106.  @Use95:
  1107. {Getting short filename}
  1108.   Mov           Ax,7160h
  1109.   Mov           Cx,0001h
  1110.   Lds           Si,Prog
  1111.   Les           Di,ShortFileName
  1112.   Int           21h
  1113.   Lds           Dx,ShortFileName
  1114.   Jc           @End
  1115. {Executing}
  1116.  @OK:
  1117.   Les           Bx,ParameterBlock
  1118.   Mov           Ah,4Bh
  1119.   Xor           Al,Al
  1120.   Int           21h
  1121.  @End:
  1122.   Pop           Ds
  1123. End;
  1124.  
  1125. Procedure SetDTA(Address: Pointer); Assembler;
  1126. Asm
  1127.   Push          Ds
  1128.   Mov           Ah,1Ah
  1129.   Lds           Dx,Address
  1130.   Int           21h
  1131.   Pop           Ds
  1132. End;
  1133.  
  1134. Function GetDTA: Pointer; Assembler;
  1135. Asm
  1136.   Mov           Ah,2Fh
  1137.   Int           21h
  1138.   Mov           Dx,Es
  1139.   Mov           Ax,Bx
  1140. End;
  1141.  
  1142. Function DriveInformation(Drive: TChar; Var DriveType: TByte; Volume: TPointer; Var Serial,TotalSpace,FreeSpace,
  1143.                            ClusterSize: TDouble): TBoolean; Assembler;
  1144. Asm
  1145.   Push          Ds
  1146.   Mov           Ax,440Dh
  1147.   Mov           Bl,Drive
  1148.   Sub           Bl,64
  1149.   Mov           Cx,0860h
  1150.   Lds           Dx,ParameterBlock
  1151.   Int           21h
  1152.   Mov           Al,1
  1153.   Jnc          @Continue
  1154.   Xor           Al,Al
  1155.   Jmp          @Error
  1156.  @Continue:
  1157.   Mov           Si,Dx
  1158.   Inc           Si
  1159.   LodSb
  1160.   Les           Di,DriveType
  1161.   StoSb
  1162.   Pop           Ds
  1163.   Push          Ds
  1164.   Les           Di,ParameterBlock
  1165.   Xor           Ax,Ax
  1166.   StoSw
  1167.   Lds           Dx,ParameterBlock
  1168.   Mov           Ax,440Dh
  1169.   Mov           Bl,Drive
  1170.   Sub           Bl,64
  1171.   Mov           Cx,0866h
  1172.   Int           21h
  1173.   Mov           Si,Dx
  1174.   Inc           Si
  1175.   Inc           Si
  1176.   Les           Di,Serial
  1177.   Dw            0A566h
  1178.   Les           Di,Volume
  1179.   Dw            0A566h
  1180.   Dw            0A566h
  1181.   MovSw
  1182.   MovSb
  1183.   Mov           Ah,36h
  1184.   Mov           Dl,Drive
  1185.   Sub           Dl,64
  1186.   Int           21h
  1187.   Push          Dx
  1188.   Push          Ax
  1189.   Mul           Cx
  1190.   Les           Di,ClusterSize
  1191.   StoSw
  1192.   Mov           Ax,Dx
  1193.   StoSw
  1194.   Pop           Ax
  1195.   Push          Ax
  1196.   Mul           Cx
  1197.   Mul           Bx
  1198.   Les           Di,FreeSpace
  1199.   StoSw
  1200.   Mov           Ax,Dx
  1201.   StoSw
  1202.   Pop           Ax
  1203.   Pop           Dx
  1204.   Mov           Bx,Dx
  1205.   Mul           Cx
  1206.   Mul           Bx
  1207.   Les           Di,TotalSpace
  1208.   StoSw
  1209.   Mov           Ax,Dx
  1210.   StoSw
  1211.   Mov           Al,1
  1212.  @Error:
  1213.   Pop           Ds
  1214. End;
  1215.  
  1216. Function DiskFree(Drive: TChar): TDouble; Assembler;
  1217. Asm
  1218.   Mov           Ah,36h
  1219.   Mov           Dl,Drive
  1220.   Sub           Dl,64
  1221.   Int           21h
  1222.   Cmp           Ax,0FFFFh
  1223.   Je           @Error
  1224.   Mul           Cx
  1225.   Mul           Bx
  1226.   Jmp          @End
  1227.  @Error:
  1228.   Mov           Dx,Ax
  1229.  @End:
  1230. End;
  1231.  
  1232. Function DiskSize(Drive: TChar): TDouble; Assembler;
  1233. Asm
  1234.   Mov           Ah,36h
  1235.   Mov           Dl,Drive
  1236.   Sub           Dl,64
  1237.   Int           21h
  1238.   Cmp           Ax,0FFFFh
  1239.   Je           @Error
  1240.   Mul           Cx
  1241.   Mul           Dx
  1242.   Jmp          @End
  1243.  @Error:
  1244.   Mov           Dx,Ax
  1245.  @End:
  1246. End;
  1247.  
  1248. Procedure ResetDrive(Drive: TChar); Assembler;
  1249. Asm
  1250.   Mov           Ax,710Dh
  1251.   Cmp           Using95,True
  1252.   Je           @Use95
  1253.   Mov           Ax,0D00h
  1254.  @Use95:
  1255.   Mov           Cx,01h
  1256.   Xor           Dh,Dh
  1257.   Mov           Dl,Drive
  1258.   Sub           Dx,65
  1259.   Int           21h
  1260. End;
  1261.  
  1262. Procedure TurnLedOn(Drive: TChar); Assembler;
  1263. Asm
  1264.   Mov           Al,Drive
  1265.   Sub           Al,65
  1266.   Mov           Cl,Al
  1267.   Add           Cl,4
  1268.   Mov           Ah,1
  1269.   ShL           Ah,Cl
  1270.   Add           Al,Ah
  1271.   Add           Al,12
  1272.   Mov           Dx,03F2h
  1273.   Out           Dx,Al
  1274. End;
  1275.  
  1276. Procedure TurnLedOff(Drive: TChar); Assembler;
  1277. Asm
  1278.   Mov           Al,Drive
  1279.   Sub           Al,53
  1280.   Mov           Dx,03F2h
  1281.   Out           Dx,Al
  1282. End;
  1283.  
  1284.  
  1285. Begin
  1286.  CreateAttr:=faArchive;
  1287.  FindAttr:=faArchive Or faReadOnly;
  1288.  CopyAttr:=faArchive Or faReadOnly;
  1289.  DeleteAttr:=faArchive;
  1290.  FileMode:=fmReadWrite;
  1291.  FillChar(Block,40,$00);
  1292.  ParameterBlock:=@Block;
  1293.  LockLevel:=0;
  1294.  Using95:=(Task.OS=osWin95);
  1295.  DTA:=GetDTA;
  1296. End.
  1297.  
  1298. (* UMulti - multitasker support unit *)
  1299. (*        Compile this first         *)
  1300. (* UMulti - multitasker support unit *)
  1301. (*        Compile this first         *)
  1302. (* UMulti - multitasker support unit *)
  1303. (*        Compile this first         *)
  1304. (* UMulti - multitasker support unit *)
  1305. (*        Compile this first         *)
  1306. (* UMulti - multitasker support unit *)
  1307. (*        Compile this first         *)
  1308. (* UMulti - multitasker support unit *)
  1309. (*        Compile this first         *)
  1310. (* UMulti - multitasker support unit *)
  1311. (*        Compile this first         *)
  1312. (* UMulti - multitasker support unit *)
  1313. (*        Compile this first         *)
  1314. (* UMulti - multitasker support unit *)
  1315. (*        Compile this first         *)
  1316. (* UMulti - multitasker support unit *)
  1317. (*        Compile this first         *)
  1318.  
  1319. Unit UMulti;
  1320.  
  1321. Interface uses UGlobal;
  1322.  
  1323. Const Tasker: Array [0..10] Of String[9] = ('DOS','Windows ''95','Windows','OS/2','DesqView','TopView','DoubleDos',
  1324.                                             'NetWare','MultiLink','CSwitch','EuroDOS');
  1325.  
  1326. Const osDOS = 0;
  1327.       osWin95 = 1;
  1328.       osWindows = 2;
  1329.       osOS2 = 3;
  1330.       osDesqView = 4;
  1331.       osTopView = 5;
  1332.       osDoubleDos = 6;
  1333.       osNetWare = 7;
  1334.       osMultiLink = 8;
  1335.       osCSwitch = 9;
  1336.       osEuroDOS = 10;
  1337.  
  1338. Type TaskRec = Record
  1339.       OS: Word;
  1340.       Version: Word;
  1341.       Delay: Word;
  1342.      End;
  1343.  
  1344. Const Task: TaskRec = (OS: 0;
  1345.                        Version: 0;
  1346.                        Delay: 100);
  1347.  
  1348. { Call  GiveTimeSlice  to release CPU cycles to the multitasker. }
  1349.  
  1350. { Polling  could be use as procedure to be used inside ReadKey procedures
  1351.   to read the clock, update the screen, and release CPU cycles. Polling is
  1352.   at startup the same as GiveTimeSlice }
  1353.  
  1354. Var GiveTimeSlice,
  1355.     Polling: TProc;
  1356.  
  1357. { AssignProcs  is called automatically by the startup procedure Init }
  1358. Procedure AssignProcs;
  1359.  
  1360. { ReleaseTime is a macro procedure which takes only 7 bytes, and releases
  1361.   DOS, Windows, Windows '95, and OS/2 timeslices }
  1362. Procedure ReleaseTime; Inline($CD/$28/$B8/$80/$16/$CD/$2F);
  1363.  
  1364. Implementation
  1365.  
  1366. {$F+}
  1367. Procedure NetWare_GTS; Assembler;
  1368. Asm
  1369.   Mov           Bx,000Ah
  1370.   Int           7Ah
  1371. End;
  1372.  
  1373. Procedure DoubleDOS_GTS; Assembler;
  1374. Asm
  1375.   Mov           Ax,0EE02h
  1376.   Int           21h
  1377. End;
  1378.  
  1379. Procedure Windows_Win95_OS2_GTS; Assembler;
  1380. Asm
  1381.   Mov           Ax,1680h
  1382.   Int           2Fh
  1383. End;
  1384.  
  1385. Procedure DesqView_TopView_GTS; Assembler;
  1386. Asm
  1387.   Mov           Ax,1000h
  1388.   Int           15h
  1389. End;
  1390.  
  1391. Procedure DOS_GTS; Assembler;
  1392. Asm
  1393.   Int           28h
  1394. End;
  1395.  
  1396. Procedure MultiLink_GTS; Assembler;
  1397. Asm
  1398.   Mov           Ah,02h
  1399.   Int           7Fh
  1400. End;
  1401.  
  1402. Procedure CSwitch_GTS; Assembler;
  1403. Asm
  1404.   Mov           Ah,01h
  1405.   Int           62h
  1406. End;
  1407.  
  1408. Procedure EuroDOS_GTS; Assembler;
  1409. Asm
  1410.   Mov           Ah,89h
  1411.   Xor           Cx,Cx
  1412.   Int           21h
  1413. End;
  1414. {$F-}
  1415.  
  1416. Procedure AssignProcs;
  1417. Begin
  1418.  Case Task.OS Of
  1419.   osDos: GiveTimeSlice:=DOS_GTS;
  1420.   osWin95: GiveTimeSlice:=Windows_Win95_OS2_GTS;
  1421.   osWindows: GiveTimeSlice:=Windows_Win95_OS2_GTS;
  1422.   osOS2: GiveTimeSlice:=Windows_Win95_OS2_GTS;
  1423.   osDesqView: GiveTimeSlice:=DesqView_TopView_GTS;
  1424.   osTopView: GiveTimeSlice:=DesqView_TopView_GTS;
  1425.   osDoubleDos: GiveTimeSlice:=DoubleDOS_GTS;
  1426.   osNetWare: GiveTimeSlice:=NetWare_GTS;
  1427.   osMultiLink: GiveTimeSlice:=MultiLink_GTS;
  1428.   osCSwitch: GiveTimeSlice:=CSwitch_GTS;
  1429.   osEuroDOS: GiveTimeSlice:=EuroDOS_GTS;
  1430.  End;
  1431. End;
  1432.  
  1433. Procedure Init; Assembler;
  1434. Asm
  1435.   Mov           Task.OS,00h
  1436.   Mov           Task.Version,00h
  1437.   Mov           Ah,87h
  1438.   Xor           Al,Al
  1439.   Int           21h
  1440.   Cmp           Al,0
  1441.   Jne          @EuroDOS
  1442.   Mov           Ah,30h
  1443.   Mov           Al,01h
  1444.   Int           21h
  1445.   Cmp           Al,14h
  1446.   Je           @OS2
  1447.   Mov           Ax,160Ah
  1448.   Int           2Fh
  1449.   Cmp           Ax,00h
  1450.   Je           @Windows
  1451.   Mov           Ax,1022h
  1452.   Mov           Bx,0000h
  1453.   Int           15h
  1454.   Cmp           Bx,00h
  1455.   Jne          @DesqView
  1456.   Mov           Ah,2Bh
  1457.   Mov           Al,01h
  1458.   Mov           Cx,4445h
  1459.   Mov           Dx,5351h
  1460.   Int           21h
  1461.   Cmp           Al,0FFh
  1462.   Jne          @TopView
  1463.   Mov           Ax,0E400h
  1464.   Int           21h
  1465.   Cmp           Al,00h
  1466.   Jne          @DoubleDos
  1467.   Mov           Ax,7A00h
  1468.   Int           2Fh
  1469.   Cmp           Al,0FFh
  1470.   Je           @NetWare
  1471.   Jmp          @End
  1472.  @Windows:
  1473.   Cmp           Bh,04h
  1474.   Jne          @Win3
  1475.   Mov           Task.OS,01h
  1476.   Jmp          @Windows_OK
  1477.  @Win3:
  1478.   Mov           Task.OS,02h
  1479.  @Windows_OK:
  1480.   Mov           Task.Version,Bx
  1481.   Jmp          @End
  1482.  @OS2:
  1483.   Mov           Task.OS,03h
  1484.   Mov           Bh,Ah
  1485.   Xor           Ah,Ah
  1486.   Mov           Cl,0Ah
  1487.   Div           Cl
  1488.   Mov           Ah,Bh
  1489.   XChg          Ah,Al
  1490.   Mov           Task.Version,Ax
  1491.   Jmp          @End
  1492.  @DesqView:
  1493.   Mov           Task.OS,04h
  1494.   Jmp          @End
  1495.  @TopView:
  1496.   Mov           Task.OS,05h
  1497.   Jmp          @End
  1498.  @DoubleDos:
  1499.   Mov           Task.OS,06h
  1500.   Jmp          @End
  1501.  @NetWare:
  1502.   Mov           Task.OS,07h
  1503.   Jmp          @End
  1504.  @MultiLink:
  1505.   Mov           Task.OS,08h
  1506.   Jmp          @End
  1507.  @CSwitch:
  1508.   Mov           Task.OS,09h
  1509.   Jmp          @End
  1510.  @EuroDOS:
  1511.   Mov           Task.OS,10h
  1512.  @End:
  1513.   Call          AssignProcs
  1514. End;
  1515.  
  1516. Begin
  1517.  Init;
  1518.  Polling:=GiveTimeSlice;
  1519. End.